package question5.com.qee.jdbc;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName: learning
 * @Package: question5.com.qee.jdbc
 * @ClassName: Session
 * @Description:
 * @Version: 1.0
 */
public interface Session {


    <T> List<T> selectList(String sql, Map<String, Object> paramMap, Class<T> resultType) throws SQLException, IllegalAccessException, InstantiationException;


    <T> T selectOne(String sql, Map<String, Object> paramMap, Class<T> resultType) throws IllegalAccessException, SQLException, InstantiationException;


    int insert(String sql, Map<String, Object> paramMap) throws SQLException;


    int batchInsert(String sql, List<Map<String, Object>> paramList) throws SQLException;


    int update(String sql, Map<String, Object> paramMap) throws SQLException;


    default <T> List<T> getResult(Class<T> resultType, ResultSet resultSet) throws SQLException, InstantiationException, IllegalAccessException {
        List<T> result = new ArrayList<>();
        Field[] declaredFields = resultType.getDeclaredFields();
        if (resultSet != null) {
            while (resultSet.next()) {
                T newInstance = resultType.newInstance();
                for (Field field : declaredFields) {
                    String columnName = AbcUtils.humpToLine(field.getName());
                    Object value = null;
                    if (field.getType() == String.class) {
                        value = resultSet.getString(columnName);

                    } else if (field.getType() == Integer.class
                            || field.getType() == int.class) {
                        value = resultSet.getInt(columnName);
                        if (field.getAnnotation(NullAble.class) != null && (int) value == 0) {
                            value = null;
                        }
                    } else if (field.getType() == Long.class
                            || field.getType() == long.class) {
                        value = resultSet.getLong(columnName);
                        if (field.getAnnotation(NullAble.class) != null && (long) value == 0) {
                            value = null;
                        }
                    } else if (field.getType() == Date.class) {
                        value = resultSet.getDate(columnName);
                    } else if (field.getType() == Timestamp.class) {
                        value = resultSet.getTimestamp(columnName);
                    }
                    field.setAccessible(true);
                    field.set(newInstance, value);
                }
                result.add(newInstance);
            }
        }
        return result;
    }


}
